package com.atguigu.guli.service.trade.service.impl;

import com.atguigu.guli.common.util.HttpClientUtils;
import com.atguigu.guli.service.base.exception.GuliException;
import com.atguigu.guli.service.base.result.ResultCodeEnum;
import com.atguigu.guli.service.trade.entity.Order;
import com.atguigu.guli.service.trade.service.OrderService;
import com.atguigu.guli.service.trade.service.WeixinPayService;
import com.atguigu.guli.service.trade.util.WeixinPayProperties;
import com.github.wxpay.sdk.WXPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lsj
 * @create 2021-07-19 18:36
 */
@Service
@Slf4j
public class WeixinPayServiceImpl implements WeixinPayService {

    @Autowired
    private WeixinPayProperties weixinPayProperties;

    @Autowired
    private OrderService orderService;

    @Override
    public Map<String, Object> createNative(String orderNo, String remoteAddr) {

        //通过订单号获取订单
        Order order = orderService.getOrderByOrderNo(orderNo);

        //创建httpClinet发送远程请求
//        HttpClientUtils client = new HttpClientUtils("https://api.mch.weixin.qq.com/pay/unifiedorder"); // 真实微信系统
        HttpClientUtils client = new HttpClientUtils("https://api.mch.weixin.qq.com/sandboxnew/pay/unifiedorder"); //沙箱
        //组装参数
        HashMap<String, String> params = new HashMap<>();
        params.put("appid", weixinPayProperties.getAppId()); // 公众号中获取
        params.put("mch_id", weixinPayProperties.getPartner()); // 商户号中获取
        params.put("nonce_str", WXPayUtil.generateNonceStr()); // 生成随机字符串,防止请求重放攻击
//        params.put("sign", WXPayUtil.generateSignature());
        params.put("body", order.getCourseTitle()); // 商品描述
        params.put("out_trade_no", orderNo); // 统一下单成功后并支付完成后，订单号不能重复
        params.put("total_fee", order.getTotalFee() + ""); // 商户订单号,注意，这里必须使用字符串类型的参数（总金额：分）
        params.put("spbill_create_ip", remoteAddr); // 终端IP
        params.put("notify_url", weixinPayProperties.getNotifyUrl()); // 回调url
        params.put("trade_type","NATIVE"); // 交易类型
        params.put("product_id",order.getCourseId()); //可选 (trade_type=NATIVE时，此参数必传。此参数为二维码中包含的商品ID，商户自行定义。)
//        params.put("sign", WXPayUtil.generateSignature(params, weixinPayProperties.getPartnerKey()));

        //将参数转换成xml
        String xmlParams = null;
        try {
            xmlParams = WXPayUtil.generateSignedXml(params, weixinPayProperties.getPartnerKey());

            System.out.println(xmlParams);

            //将请求参数设置到客户端对象中
            client.setXmlParam(xmlParams);
            client.setHttps(true);
            //发送请求
            client.post();
            //得到响应
            String resultXml = client.getContent();
            //解析结果
            Map<String, String> resultMap = WXPayUtil.xmlToMap(resultXml);

            //处理错误
            //错误处理
            if("FAIL".equals(resultMap.get("return_code")) || "FAIL".equals(resultMap.get("result_code"))){
                log.error("微信支付统一下单错误 - "
                        + "return_code: " + resultMap.get("return_code")
                        + "return_msg: " + resultMap.get("return_msg")
                        + "result_code: " + resultMap.get("result_code")
                        + "err_code: " + resultMap.get("err_code")
                        + "err_code_des: " + resultMap.get("err_code_des"));

                throw new GuliException(ResultCodeEnum.PAY_UNIFIEDORDER_ERROR);
            }

            //组装需要的内容 （这些内容不是一开始就知道，是要先知道前端需要什么数据）
            HashMap<String, Object> map = new HashMap<>();
            map.put("code_url", resultMap.get("code_url"));
            map.put("total_fee", order.getTotalFee());
            map.put("out_trade_no", orderNo);
            map.put("course_id", order.getCourseId());
            map.put("result_code", resultMap.get("result_code"));

            return map;

        } catch (Exception e) {
            throw new GuliException(ResultCodeEnum.PAY_UNIFIEDORDER_ERROR);
        }
    }
}
